#include "../include/SparseMatrix.h"

SparseMatrixTriplet::SparseMatrixTriplet(int r, int c) : rows(r), cols(c) {}

void SparseMatrixTriplet::addElement(int row, int col, int value) {
    if (value != 0) {
        data.emplace_back(row, col, value);
    }
}

SparseMatrixTriplet SparseMatrixTriplet::transpose() const {
    SparseMatrixTriplet result(cols, rows);
    
    for (const auto& triple : data) {
        result.addElement(triple.col, triple.row, triple.value);
    }
    
    return result;
}

void SparseMatrixTriplet::print() const {
    cout << "三元组顺序表:" << endl;
    cout << "行\t列\t值" << endl;
    for (const auto& triple : data) {
        cout << triple.row << "\t" << triple.col << "\t" << triple.value << endl;
    }
}

void SparseMatrixTriplet::interactiveInput() {
    cout << "请输入稀疏矩阵的非零元素（输入-1结束）:" << endl;
    while (true) {
        int row = Utils::getIntInput("行号 (0-" + to_string(rows-1) + "): ");
        if (row == -1) break;
        if (row < 0 || row >= rows) {
            cout << "行号超出范围！" << endl;
            continue;
        }
        
        int col = Utils::getIntInput("列号 (0-" + to_string(cols-1) + "): ");
        if (col == -1) break;
        if (col < 0 || col >= cols) {
            cout << "列号超出范围！" << endl;
            continue;
        }
        
        int value = Utils::getIntInput("值: ");
        if (value == -1) break;
        
        addElement(row, col, value);
        cout << "元素添加成功！" << endl;
        
        char cont;
        cout << "继续添加？(y/n): ";
        cin >> cont;
        Utils::clearInputBuffer();
        if (cont != 'y' && cont != 'Y') break;
    }
}

SparseMatrixCross::SparseMatrixCross(int r, int c) : rows(r), cols(c) {
    rowHeads.resize(rows, nullptr);
    colHeads.resize(cols, nullptr);
}

void SparseMatrixCross::addElement(int row, int col, int value) {
    if (value == 0) return;
    
    auto newNode = make_shared<CrossNode>(row, col, value);
    
    if (!rowHeads[row] || col < rowHeads[row]->col) {
        newNode->right = rowHeads[row];
        rowHeads[row] = newNode;
    } else {
        auto current = rowHeads[row];
        shared_ptr<CrossNode> prev = nullptr;
        while (current && current->col < col) {
            prev = current;
            current = current->right;
        }
        if (prev) {
            prev->right = newNode;
            newNode->right = current;
        }
    }
    
    if (!colHeads[col] || row < colHeads[col]->row) {
        newNode->down = colHeads[col];
        colHeads[col] = newNode;
    } else {
        auto current = colHeads[col];
        shared_ptr<CrossNode> prev = nullptr;
        while (current && current->row < row) {
            prev = current;
            current = current->down;
        }
        if (prev) {
            prev->down = newNode;
            newNode->down = current;
        }
    }
}

SparseMatrixCross SparseMatrixCross::transpose() const {
    SparseMatrixCross result(cols, rows);
    
    for (int i = 0; i < rows; i++) {
        auto current = rowHeads[i];
        while (current) {
            result.addElement(current->col, current->row, current->value);
            current = current->right;
        }
    }
    
    return result;
}

void SparseMatrixCross::print() const {
    cout << "十字链表:" << endl;
    for (int i = 0; i < rows; i++) {
        auto current = rowHeads[i];
        while (current) {
            cout << "(" << current->row << "," << current->col << ")=" << current->value << " ";
            current = current->right;
        }
        if (rowHeads[i]) cout << endl;
    }
}

void SparseMatrixCross::interactiveInput() {
    cout << "请输入稀疏矩阵的非零元素（输入-1结束）:" << endl;
    while (true) {
        int row = Utils::getIntInput("行号 (0-" + to_string(rows-1) + "): ");
        if (row == -1) break;
        if (row < 0 || row >= rows) {
            cout << "行号超出范围！" << endl;
            continue;
        }
        
        int col = Utils::getIntInput("列号 (0-" + to_string(cols-1) + "): ");
        if (col == -1) break;
        if (col < 0 || col >= cols) {
            cout << "列号超出范围！" << endl;
            continue;
        }
        
        int value = Utils::getIntInput("值: ");
        if (value == -1) break;
        
        addElement(row, col, value);
        cout << "元素添加成功！" << endl;
        
        char cont;
        cout << "继续添加？(y/n): ";
        cin >> cont;
        Utils::clearInputBuffer();
        if (cont != 'y' && cont != 'Y') break;
    }
}

void SparseMatrixCross::testSparseMatrix() {
    cout << "=== 稀疏矩阵测试 ===" << endl;
    
    SparseMatrixTriplet triplet(4, 5);
    triplet.addElement(0, 1, 3);
    triplet.addElement(0, 4, 7);
    triplet.addElement(1, 0, 1);
    triplet.addElement(1, 2, 5);
    triplet.addElement(2, 3, 2);
    triplet.addElement(3, 1, 6);
    triplet.addElement(3, 4, 9);
    
    cout << "原始矩阵:" << endl;
    triplet.print();
    
    cout << "转置矩阵:" << endl;
    auto transposedTriplet = triplet.transpose();
    transposedTriplet.print();
    
    cout << endl;
    
    SparseMatrixCross cross(4, 5);
    cross.addElement(0, 1, 3);
    cross.addElement(0, 4, 7);
    cross.addElement(1, 0, 1);
    cross.addElement(1, 2, 5);
    cross.addElement(2, 3, 2);
    cross.addElement(3, 1, 6);
    cross.addElement(3, 4, 9);
    
    cout << "原始矩阵:" << endl;
    cross.print();
    
    cout << "转置矩阵:" << endl;
    auto transposedCross = cross.transpose();
    transposedCross.print();
}

void SparseMatrixCross::interactiveTest() {
    cout << "=== 稀疏矩阵交互式测试 ===" << endl;
    
    while (true) {
        cout << "\n请选择操作：" << endl;
        cout << "1. 创建新矩阵并测试" << endl;
        cout << "2. 使用默认示例" << endl;
        cout << "0. 返回主菜单" << endl;

        int choice = Utils::getIntInput("请输入选择 (0-2): ");

        if (choice == 0) break;

        if (choice == 1) {
            int rows = Utils::getIntInput("请输入矩阵行数: ");
            int cols = Utils::getIntInput("请输入矩阵列数: ");
            
            cout << "\n=== 三元组顺序表测试 ===" << endl;
            SparseMatrixTriplet triplet(rows, cols);
            triplet.interactiveInput();
            
            cout << "\n原始矩阵:" << endl;
            triplet.print();
            
            cout << "\n转置矩阵:" << endl;
            auto transposedTriplet = triplet.transpose();
            transposedTriplet.print();
            
            cout << "\n=== 十字链表测试 ===" << endl;
            SparseMatrixCross cross(rows, cols);
            cross.interactiveInput();
            
            cout << "\n原始矩阵:" << endl;
            cross.print();
            
            cout << "\n转置矩阵:" << endl;
            auto transposedCross = cross.transpose();
            transposedCross.print();
            
        } else if (choice == 2) {
            testSparseMatrix();
        } else {
            cout << "无效选择！" << endl;
        }
    }
}